package Square;


import java.awt.Color;
import java.awt.FlowLayout;

import javax.swing.JLabel;
import javax.swing.JPanel;

import Monopol.AssetGroups.AssetGroup;
import Monopol.AssetGroups.State;
import Monopol.MonopolExceptions.InsufficientFunds;
import Player.Player;

/**
 * @author Avia Tam
 * @author Assaf Miron
 * 
 */
public class City extends Square implements Negotiable {
	private static final Integer MAX_HOUSES = 3;
	private Double [] stay_price; // Four Price Values
	private Double cost; // Cost of the City
	private Double house_price; // Cost of building Each House
	private Integer num_of_houses; // Indicator for the Number of Houses built
	private State state;// The State that this City relates to
	private Player owner; // The Player who Owns this Square

	/**
	 * @param name
	 * @param stay_price
	 * @param cost
	 * @param house_price
	 * @param state
	 */
	public City(String name, Double[] stay_price, Double cost, Double house_price, State state) {
		super(name); // Construct Square 
		this.stay_price = stay_price; // Initialize the Stay Price Array
		this.cost = cost; // Initialize the Cost of the City
		this.house_price = house_price; // Initialize the Cost of each House
		this.num_of_houses = 0; // Initialize the number of houses - no Houses
		this.state = state; // Initialize the State
	}


	// Stay Price Getter and Setter
	public Double getStay_price() {
		return stay_price[num_of_houses];
	}
	
	public void setStay_price(Double[] stay_price) {
		this.stay_price = stay_price;
	}
	// End-Stay Price Getter and Setter
	
	// Cost Getter and Setter
	public Double getCost() {
		return cost;
	}
	
	public void setCost(Double cost) {
		this.cost = cost;
	}
	// End-Cost Getter and Setter
	
	// House Price Getter and Setter
	public Double getHouse_price() {
		return house_price;
	}
	
	public void setHouse_price(Double house_price) {
		this.house_price = house_price;
	}
	// End - House Price Getter and Setter
	
	// Number of Houses Getter and Setter
	public Integer getNum_of_houses() {
		return num_of_houses;
	}
	// End - Number of Houses Getter and Setter
	
	
	// State Getter and Setter
	public State getState() {
		return state;
	}
	public void setState(State state) {
		this.state = state;
	}
	// End- State Getter and Setter
	

	/**
	 * @param player The square owner
	 */
	@Override
	public void setOwner(Player player)
	{
		this.owner = player;
	}
	
	@Override
	public Player getOwner() 
	{
		return owner;
	}
	
	/**
	 * @return If the city can be bought
	 */
	public boolean isBuyable() {
		// Check if This Service has an Owner
		if(this.getOwner() == null)
			return true; // No Owner - Can be Bought
		else
			return false; // This Service has an Owner - Can't be bought 
	}

	/**
	 * @return If the city can be sold
	 */
	@Override
	public boolean isSellable() {
		// Check if this Service has an Owner or not
		if(this.getOwner() != null)
			return true; // The Owner can Sell this Service
		else
			return false; // There is no Owner to the Service
	}


	/* (non-Javadoc)
	 * @see Square.Negotiable#buy(Player.Player)
	 */
	@Override
	public void buy(Player player) throws InsufficientFunds {
		// Check if the Player have enough Funds to buy this Service
		if(player.getFunds() >= this.cost)
		{
			// Take the Money from the Player
			player.addFunds(-this.cost);
			// Set the Player as the Owner of this Service
			this.setOwner(player);
		}
		else
			// Insufficient Funds
			throw new InsufficientFunds("Insufficient Funds, can't buy ");
		
	}
	
	
	@Override
	public void sell(Player player) 
	{
		// Change the Owner of this City
		this.owner = player;
	}
	
	/**
	 * Prints out The City Description
	 */
	@Override
	public String toString() 
	{
		String message = super.toString() + " ("+ state.getName() + ")\n";
		
		// Check that there is a Owner
		if(owner != null)
		{
			message = message + 
			"Stay Price: " + stay_price[num_of_houses] + "\n" +
			"House Cost: " + house_price + "\n" +
			"City Owner: " + owner.getName();
		}
		else // No Owner
		{
			message = message + 
			"City Cost: " + cost.toString() + "\n" + 
			"Stay Price: \n" +
			"\tNo Houses: " + stay_price[0] + "\n" +
			"\tOne House: " + stay_price[1] + "\n" +
			"\tTwo Houses: " + stay_price[2] + "\n" +
			"\tThree Houses: " + stay_price[3] + "\n" +
			"City Owner: NONE";
		}
		// Return the Message
		return message;	                             
	}

	@Override
	public boolean isAsset(){
		return true;
	}
	
	/**
	 * verify and sells a house to the city owner if possible
	 */
	public void buyHouse(Player player)throws InsufficientFunds {
		// Check if the Player have enough Funds to buy this Service
		if(player.getFunds() >= this.getHouse_price())
		{
			// Check that the Player wont buy more houses than it can
			if(this.num_of_houses < MAX_HOUSES)
			{
				// Take the Money from the Player
				player.addFunds(-this.getHouse_price());
				//Raise house on state flag 
				this.state.setIsHouseExists(true);
				// Increment the House Number
				this.num_of_houses++;
			}
		}
		else
			// Insufficient Funds
			throw new InsufficientFunds("Insufficient Funds, can't buy a house ");
		
	}

	@Override
	public Boolean isCity() {
		return true;
	}
	
	@Override
	public void deleteOwner() {
		// Clear Owner
		owner = null;
		// Clear Number Of Houses
		num_of_houses = 0;
		// Clear the House Flag
		state.setIsHouseExists(false);
	}
	
	@Override
	public AssetGroup getGroup()
	{
		return state;
	}
	
	@Override
	public Color getColor()
	{
		// Check if there is an Owner for this Service
		if (owner != null)
			// Return the Owner Player Color
			return owner.getColor();
		else
			// Return a Default Color
			return state.getColor();
	}
	
	/**
	 * @return The City Details
	 */
	public String getDetails()
	{
		String retDetails;
		
		retDetails = "<HTML><H2>State: " + state.getName() + "</H2><BR>" + 
		"City Cost: " + cost.toString() + "<BR>" +
		"House Cost: " + "<B>" + house_price + "</B><BR>" +
		"Stay Price: <BR>" +
		"\tNo Houses: " + "<B>" + stay_price[0] + "</B><BR>" +
		"\tOne House: " + "<B>" + stay_price[1] + "</B><BR>" +
		"\tTwo Houses: " + "<B>" + stay_price[2] + "</B><BR>" +
		"\tThree Houses: " + "<B>" + stay_price[3] + "</B><BR>" + 
		"\tCity Owner: ";

		// Check that there is a Owner
		if(owner != null)
		{			
			retDetails = retDetails + "<B>" + owner.getName()+ "</B>";
		}
		else // No Owner
		{
			retDetails = retDetails + "<B>NONE</B>";
		}
		
		// Return the City Details
		return retDetails + "</HTML>";
	}
	
	@Override
	public JPanel draw()
	{
		// Create the Main Panel
		JPanel pnDetails = new JPanel();
		pnDetails.setLayout(new FlowLayout());
		pnDetails.setOpaque(false);
		
		// Create the Detail Labels
		JLabel lblDetails = new JLabel(getDetails(),JLabel.CENTER);
		
		// Add the Details Label to the Center
		pnDetails.add(lblDetails);

		// Return the Details Panel
		return pnDetails;
	}
}

	


